# -*- coding:utf-8 -*-
# @Author : mistchan
# @Time : 2021/5/19 0019 00:02
# @File : file_watcher.py
# @Software: PyCharm

import shutil
import time
import datetime
import os
import glob
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from PIL import Image, ImageTk
import merge_pictures
import merge_pdfs
import main

# 微信的相关账号的缓存目录
file_dir = 'F:\\wechatfiles\\WeChat Files\\wxid_3hw3iuivu73o22\\FileStorage\\File'
image_dir = 'F:\\wechatfiles\\WeChat Files\\wxid_3hw3iuivu73o22\\FileStorage\\Image'

dirt_name = time.strftime('%Y%m%d', time.localtime())
files_to_watch = os.path.join(file_dir, os.listdir(file_dir)[-1])
images_to_watch = os.path.join(image_dir, os.listdir(image_dir)[-2])
if not os.path.isdir('.\\手动放入需要合并的文件'):
    os.mkdir('.\\手动放入需要合并的文件')
else:
    shutil.rmtree('.\\手动放入需要合并的文件')
    os.mkdir('.\\手动放入需要合并的文件')


others_to_watch = '.\\手动放入需要合并的文件'

# 解密微信image缓存里加密的图片
def get_code(file_path):
    if not os.path.isdir('.\\dat_temp'):
        os.mkdir('.\\dat_temp')
    pic_head = [0xff, 0xd8, 0x89, 0x50, 0x47, 0x49]
    # 图片字节头信息，
    # [0][1]为jpg头信息，
    # [2][3]为png头信息，
    # [4][5]为gif头信息
    """
    自动判断文件类型，并获取dat文件解密码
    :param file_path: dat文件路径
    :return: 如果文件为jpg/png/gif格式，则返回解密码，否则返回0
    """
    file_path_copied = f'.\\dat_temp\\{os.path.basename(file_path)}'
    time.sleep(0.5)
    shutil.copy(file_path, os.path.abspath(file_path_copied))
    dat_file = open(file_path_copied, "rb")
    dat_read = dat_file.read(2)
    head_index = 0
    while head_index < len(pic_head):
    # 使用第一个头信息字节来计算加密码
    # 第二个字节来验证解密码是否正确
        code = dat_read[0] ^ pic_head[head_index]
        idf_code = dat_read[1] ^ code
        head_index += 1
        if idf_code == pic_head[head_index]:
            dat_file.close()
            return code
        head_index += 1

    print("not jpg, png, gif")
    return 0


def decode_dat(file_path):
    """
    解密文件，并生成图片
    :param file_path: dat文件路径
    :return: 无
    """
    if not os.path.isdir('.\\image_temp'):
        os.mkdir('.\\image_temp')
    decode_code = get_code(file_path)
    dat_file = open(file_path, "rb")
    pic_name = os.path.basename(file_path).split('.')[0] + ".jpg"
    pic_write = open(f'.\\image_temp\\{pic_name}', "wb")
    for dat_data in dat_file:
        for dat_byte in dat_data:
            pic_data = dat_byte ^ decode_code
            pic_write.write(bytes([pic_data]))
    dat_file.close()
    pic_write.close()
    return f'.\\image_temp\\{pic_name}'


def ini_dirt(*args):
    for i in args:
        if os.path.exists(f'.\\{i}'):
            shutil.rmtree(f'.\\{i}')
        os.mkdir(f'.\\{i}')


class MyHandler(FileSystemEventHandler):
    def __init__(self, app):

        super().__init__()
        self.app = app

    def on_created(self, event):

        if event.src_path.lower().endswith('.dat'):

            image_path = decode_dat(event.src_path)
            self.app.info.set("图片:%s" % os.path.basename(image_path))
            self.app.update()
            self.app.generate_checkbtn(image_path)
            self.app.update()
        elif event.src_path.lower().endswith('.pdf'):
            self.app.generate_checkbtn(event.src_path)
            self.app.update()
            self.app.info.set("文件:%s" % os.path.basename(event.src_path))
            self.app.update()


class MainWindow(tk.Tk):
    def __init__(self):
        super().__init__()
        self.wm_attributes('-topmost', 1)
        self.overrideredirect(False)
        sw = self.winfo_screenwidth()
        # sh = self.winfo_screenheight()
        self.file_list = []
        self.file_to_show = []
        self.file_to_del = []
        self.var = {}
        ww = 500
        wh = 1200
        self.geometry("%dx%d+%d+%d" % (ww, wh, sw - ww, 50))
        self.attributes('-alpha', 0.85)
        self.after(1, lambda: self.focus_force())
        self.title('报销助手v1.0 --by cbl')
        self.info = tk.StringVar()
        self.info.set("运行中...")
        ttk.Label(textvariable=self.info, font=('微软雅黑', 10)).pack()
        btn_frame = tk.Frame()
        btn_frame.pack()
        btn_ok = ttk.Button(btn_frame, text='打印', command=self.ok, )
        btn_ok.pack(side=tk.LEFT, padx=10)
        btn_email = ttk.Button(btn_frame, text='邮件', command=self.read_email, )
        btn_email.pack(side=tk.LEFT, padx=10)
        btn_jpg = ttk.Button(btn_frame, text='手动放入文件', command=self.manully_merge_jpg, )
        btn_jpg.pack(side=tk.LEFT, padx=10)
        # btn_pdf = ttk.Button(btn_frame, text='合并pdf', command=self.manully_merge_pdf, )
        # btn_pdf.pack(side=tk.LEFT, padx=10)
        btn_frame_2 = tk.Frame()
        btn_frame_2.pack()
        btn_reset = ttk.Button(btn_frame_2, text='重置', command=self.manully_reset, )
        btn_reset.pack(side=tk.LEFT, padx=10)
        btn_cancel = ttk.Button(btn_frame_2, text='退出', command=self.cancel, )
        btn_cancel.pack(side=tk.LEFT, padx=10)
        self.checkbtn_frame = tk.Frame(self)
        self.checkbtn_frame.pack()
        
    def generate_checkbtn(self, image_path):
        self.checkbtn_frame.destroy()
        self.checkbtn_frame = tk.Frame(self)
        self.file_list.append(image_path)
        self.file_to_show.append(image_path)
        
        for k in self.file_to_show:
            self.var[k] = tk.BooleanVar()
            self.file_name = os.path.basename(k)
            if k.endswith('.jpg'):
                self.im = Image.open(k)
                
            else:
                self.im = Image.open('pdf.jpg')
            x, y = self.im.size
            x_ = 50
            self.im_resized = self.im.resize((int(x_*x/y), x_),Image.ANTIALIAS)
            self.img=ImageTk.PhotoImage(self.im_resized)
            r = ttk.Checkbutton(self.checkbtn_frame, text=self.file_name, variable=self.var[k], image=self.img, compound=tk.LEFT)
            r.img =self.img
            r.pack(anchor=tk.W)
        self.checkbtn_frame.pack()
    def manully_reset(self):
        self.file_to_show = []
        self.checkbtn_frame.destroy()
        self.checkbtn_frame = tk.Frame(self)
    def read_email(self):
        self.info.set("正在读取邮件...")
        self.update()
        mail_num = main.get_email_content('.\\手动放入需要合并的文件')
        self.info.set(f"共读取到{mail_num}封邮件！")
        self.update()
    def manully_merge_jpg(self):
        os.startfile('手动放入需要合并的文件')
    def manully_merge_pdf(self):
        pass
        
    def ok(self):
        comfirmations= messagebox.askokcancel(title='请确认', message='是否已经选择完毕，按确定开始打印！') 
        if comfirmations:
            for k, v in self.var.items():
                if v.get():               
                    self.file_to_del.append(k)
            file_to_collect = list(set(self.file_list) - set(self.file_to_del))
            pdf_file = [pdf for pdf in file_to_collect if pdf.endswith('.pdf')]
            jpg_file = [jpg for jpg in file_to_collect if jpg.endswith('.jpg')]

            if jpg_file:
                merge_pictures.join_image(file_to_collect)
                for each in glob.glob('.\\images_joined\\*'):

                    merge_pictures.print_img(each)
            if pdf_file:
                merge_pdfs.merge_to_one(file_to_collect)
            self.destroy()
        

    def cancel(self):
        observer_files.stop()
        observer_images.stop()
        self.destroy()


if __name__ == '__main__':
    ini_dirt('images', 'pdfs')
    observer_files = Observer()
    observer_images = Observer()
    observer_others = Observer()

    app = MainWindow()

    event_handler = MyHandler(app)
    observer_files.schedule(event_handler, path=files_to_watch, recursive=False)
    observer_images.schedule(event_handler, path=images_to_watch, recursive=False)
    observer_others.schedule(event_handler, path=others_to_watch, recursive=False)
    observer_files.start()
    observer_images.start()
    observer_others.start()
    app.mainloop()
    
    observer_files.join()
    observer_images.join()
    